// 跟数字有关的工具函数，可以在这里添加

import Decimal from 'decimal.js';
import type { ConfigItem } from '@/types/tester';
import { log } from '@/utils';
import { ohm, current, voltage, voltageRate, ohmRate, currentRate, capacitance, capacitanceRate, seconds, secondsRate } from '@/modules/const';

type UnitTypes = {
  value: Array<string>;
  rate: number;
};

/**
 * 精度
 */
export const precisionNumber = (value: number | string, precision = 2) => {
  return new Decimal(value).toDecimalPlaces(precision).toNumber();
};

export const unitTypes: { [key: string]: UnitTypes } = {
  voltage: {
    value: voltage,
    rate: voltageRate,
  },
  current: {
    value: current,
    rate: currentRate,
  },
  ohm: {
    value: ohm,
    rate: ohmRate,
  },
  capacitance: {
    value: capacitance,
    rate: capacitanceRate,
  },
  seconds: {
    value: seconds,
    rate: secondsRate,
  },
};

/**
 * 单位转换函数
 */
export function unitConversion(value: ConfigItem['value'] | undefined, targetUnit: string, originalUnit: string) {
  if (value === void 0 || value === '') return '';

  // 如果转换单位与原始单位相同，直接返回原值
  if (originalUnit === targetUnit) {
    return value;
  }

  // 判断单位类型
  const itemUnitType = Object.keys(unitTypes).find(type => unitTypes[type].value.includes(originalUnit));
  if (!itemUnitType) return value;

  const units = unitTypes[itemUnitType];

  // 转换单位序号
  const index = units.value.indexOf(targetUnit);
  // 当前单位序号
  const targetIndex = units.value.indexOf(originalUnit);

  if (index === -1 || targetIndex === -1) return value;

  const rate = Math.pow(units.rate, targetIndex - index);

  const res = new Decimal(value).mul(rate).toNumber();

  log(`${value} ${originalUnit} 转换为 ${res} ${targetUnit}`);

  return res;
}

/**
 * 从给定的字符串中提取第一个数字。
 * @param {string} str 需要提取数字的字符串
 * @returns {number|null} 返回提取的第一个数字，如果字符串为空或没有数字，返回 null
 */
export const extractFirstNumberSafe = (str: string) => {
  const match = str.match(/\d+\.?\d*/g);
  return match ? Number(match[0]) : null;
};

/**
 * 使用 Decimal.js 计算数字数组的精确平均值
 * @param numbers 数字数组（支持 number | string）
 * @param precision 小数位数（默认保留 2 位）
 * @returns Decimal 实例表示的精确平均值
 */
export function getAverageDecimal(numbers: (number | string)[], precision: number = 2): Decimal {
  if (numbers.length === 0) {
    throw new Error('无法计算空数组的平均值');
  }

  // 将所有元素转为 Decimal
  const decimals = numbers.map(n => new Decimal(n));

  // 求和
  const sum = decimals.reduce((acc, d) => acc.plus(d), new Decimal(0));

  // 除以数量（使用 Decimal 除法，避免精度丢失）
  const avg = sum.div(decimals.length);

  // 四舍五入到指定精度（可选）
  return avg.toDP(precision, Decimal.ROUND_HALF_UP);
}

/**
 * 将一个数组分割成多个小数组，每个小数组的长度为 chunkSize
 * @param {T[]} array 需要分割的数组
 * @param {number} chunkSize 小数组的长度
 * @returns {T[][]} 分割后的数组
 */
export function chunkArray<T>(array: T[], chunkSize: number): T[][] {
  if (chunkSize <= 0) throw new Error('chunkSize 必须大于 0');

  return Array.from({ length: Math.ceil(array.length / chunkSize) }, (_, index) =>
    array.slice(index * chunkSize, (index + 1) * chunkSize)
  );
}
